package com.ba.base.view.file

import android.annotation.TargetApi
import android.content.res.Configuration
import android.os.Build
import android.os.Environment
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.GridLayoutManager
import com.ba.base.api.ApiFile
import com.ba.base.model.vo.UploadFileEntity
import com.ba.base.model.vo.UploadResult
import com.screx.mcloud.lib.utils.ImagePickHelper
import com.ba.base.view.AddFileAdapter
import com.ba.base.view.dialog.ProgressDialog
import com.ypx.imagepicker.bean.ImageItem
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import qsos.lib.base.callback.OnTListener
import qsos.lib.base.utils.LogUtil
import qsos.lib.base.utils.ToastUtils
import qsos.lib.netservice.ApiEngine
import qsos.lib.netservice.expand.retrofit
import qsos.lib.netservice.file.UploadBody
import timber.log.Timber
import vip.qsos.lib.select.OnSelectListener
import vip.qsos.lib.select.Operation
import java.io.File
import java.util.*
import kotlin.coroutines.CoroutineContext

/**
 *
 *
 * 文件提交
 * @param singleType 限制附件单一类型，视频
 */
class VideoFilePostHelper(
    val activity: AppCompatActivity,
    val mJob: CoroutineContext = Dispatchers.Main + Job(),
    private val singleType: Boolean = false
) {

    val mAdapter: AddFileAdapter<ImageItem> = AddFileAdapter()
    val mManager = GridLayoutManager(activity, 4)

    private val mFileAdd = AddFileAdapter.TemFile<ImageItem>(true)
    private val mImage = arrayListOf<ImageItem>()
    private var mVideo: AddFileAdapter.TemFile<ImageItem>? = null
    private var hasVideo: Boolean = false
    private var mDialog: AlertDialog
    private val outputDir =
        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
            .absolutePath

    private val inputPath: String? = null
    private val outputPath: String? = null
    private var dialog: ProgressDialog? = null

    /**获取选择的文件*/
    fun getPickedFile(): List<File> {
        val files = arrayListOf<File>()
        mVideo?.file?.path?.let { files.add(File(it)) }
        mImage.forEach {
            files.add(File(it.path))
        }
        return files
    }

    init {
        mAdapter.data.add(mFileAdd)
        mAdapter.setListener(object ://单击跳转到选择视频页面
            OnTListener<AddFileAdapter.TemFile<ImageItem>> {
            override fun back(t: AddFileAdapter.TemFile<ImageItem>) {
//                pick(t)
                ImagePickHelper.video().pick(activity) {//选择完回调
                    mAdapter.data.clear()
                    it.forEach { item ->
                        if (File(item.path).length() > ImagePickHelper.LIMIT_LENGTH) {
                            ToastUtils.showToast(activity, "文件大小不能超过200M，已自动过滤")
                        } else {
                            LogUtil.d("AddFileAdapter", getFileSize(item.path).toString())
                            hasVideo = true
                            mVideo = AddFileAdapter.TemFile(item.uri, item, true)
                            mAdapter.data.add(mVideo!!)
                            LogUtil.d("AddFileAdapter", item.path.toString())
                            mImage.forEach { item ->
                                mAdapter.data.add(
                                    AddFileAdapter.TemFile(
                                        item.uri,
                                        item,
                                        false
                                    )
                                )
                            }
                            if (mVideo == null || mImage.size < 3) {
                                mAdapter.data.add(mFileAdd)
                            }
                            /**单类型模式下已选视频,则不能选其它任何附件*/
                            if (singleType && mVideo != null) {
                                mAdapter.data.remove(mFileAdd)
                            }
                            /**单类型模式下已选图片,如果图片数量已达到3张,则不能选其它任何附件,否则只能再选图片*/
                            if (singleType && mImage.size >= 3) {
                                mAdapter.data.remove(mFileAdd)
                            }
                            mAdapter.notifyDataSetChanged()
                        }
                    }

                }
            }
        })
        val mDialogBuilder = AlertDialog.Builder(activity)
        mDialogBuilder.setTitle("提示")
        mDialogBuilder.setMessage("提交中...请等待")
        mDialog = mDialogBuilder.create()
        mDialog.setCanceledOnTouchOutside(false)
        mDialog.setCancelable(false)
    }

    /**移除已选择的图片*/
    private fun deleteFile(file: AddFileAdapter.TemFile<ImageItem>) {
        if (file.video && hasVideo) {
            hasVideo = false
            mVideo = null
        }
        mImage.remove(file.file)
        mAdapter.data.remove(file)
        if (mImage.size < 4 && !mAdapter.data.contains(mFileAdd)) {
            mAdapter.data.add(mFileAdd)
        }
        mAdapter.notifyDataSetChanged()
    }

    /**图片选择*/
    private fun pickFile(video: Boolean) {
        if (video) {
            ImagePickHelper.video().pick(activity) {
                mAdapter.data.clear()
                it.forEach { item ->
                    if (File(item.path).length() > ImagePickHelper.LIMIT_LENGTH) {
                        ToastUtils.showToast(activity, "文件大小不能超过200M，已自动过滤")
                    } else {
                        hasVideo = true
                        mVideo = AddFileAdapter.TemFile(item.uri, item, true)
                        mAdapter.data.add(mVideo!!)
                    }
                }
                mImage.forEach { item ->
                    mAdapter.data.add(AddFileAdapter.TemFile(item.uri, item, false))
                }
                if (mVideo == null || mImage.size < 3) {
                    mAdapter.data.add(mFileAdd)
                }
                /**单类型模式下已选视频,则不能选其它任何附件*/
                if (singleType && mVideo != null) {
                    mAdapter.data.remove(mFileAdd)
                }
                /**单类型模式下已选图片,如果图片数量已达到3张,则不能选其它任何附件,否则只能再选图片*/
                if (singleType && mImage.size >= 3) {
                    mAdapter.data.remove(mFileAdd)
                }
                mAdapter.notifyDataSetChanged()
            }
        } else {
            ImagePickHelper.image(mImage).pick(activity) {
                mAdapter.data.clear()
                mVideo?.let {
                    hasVideo = true
                    mAdapter.data.add(mVideo!!)
                }
                mImage.clear()
                it.forEach { item ->
                    if (File(item.path).length() > ImagePickHelper.LIMIT_LENGTH) {
                        ToastUtils.showToast(activity, "有张图片大小不能超过200M，已自动过滤")
                    } else {
                        mImage.add(item)
                        mAdapter.data.add(AddFileAdapter.TemFile(item.uri, item, false))
                    }
                }

                if (mVideo == null || mImage.size < 3) {
                    mAdapter.data.add(mFileAdd)
                }
                /**单类型模式下已选视频,则不能选其它任何附件*/
                if (singleType && mVideo != null) {
                    mAdapter.data.remove(mFileAdd)
                }
                /**单类型模式下已选图片,如果图片数量已达到3张,则不能选其它任何附件,否则只能再选图片*/
                if (singleType && mImage.size >= 3) {
                    mAdapter.data.remove(mFileAdd)
                }
                mAdapter.notifyDataSetChanged()
            }
        }
    }

    /**附件列表点击*/
    fun pick(t: AddFileAdapter.TemFile<ImageItem>) {
        if (t.add) {
            if (hasVideo) {
                if (singleType) {
                    /**已选视频,单类型下不可继续选择*/
                    return
                }
                if (mImage.size < 3) {
                    pickFile(true)
                }
            } else {
                if (mImage.size < 3) {
                    /**未选视频,且图片未达3张,可以选图片或视频*/
                    /*如果已选图片,则单类型下只能继续选图片,否则可以选图片或视频*/
                    if (mImage.isNotEmpty() && singleType) {
                        pickFile(false)
                    } else {
                        SelectHelper.selectOfSingle(
                            activity = activity,
                            operations = arrayListOf(
                                Operation("图片"),
                                Operation("视频")
                            ),
                            listener = object : OnSelectListener<Operation> {
                                override fun select(data: Operation) {
                                    when (data.key) {
                                        "图片" -> {
                                            pickFile(false)
                                        }
                                        "视频" -> {
                                            pickFile(true)
                                        }
                                    }
                                }
                            })
                    }
                } else if (!singleType) {
                    /**未选视频,且图片已达3张,但不是单类型,可以且只能选视频*/
                    pickFile(true)
                }
            }
        } else {
            deleteFile(t)
        }
    }

    fun hintDialog() {
        if (mDialog.isShowing) {
            mDialog.dismiss()
        }
    }

    /**上传所选文件*/
    fun postFile(
        success: OnTListener<List<UploadFileEntity>>,
        failed: OnTListener<String>
    ) {
        mDialog.show()
        if (getPickedFile().isEmpty()) {
            success.back(arrayListOf())
            return
        }
        val parts = arrayListOf<MultipartBody.Part>()
        getPickedFile().forEach { fileEntity ->
            val requestBody =
                RequestBody.create(MediaType.parse("multipart/form-data"), fileEntity)
            val uploadBody = UploadBody(requestBody, null)
            val part: MultipartBody.Part =
                MultipartBody.Part.createFormData("file", fileEntity.name, uploadBody)
            parts.add(part)
        }
        CoroutineScope(mJob).retrofit<UploadResult> {
            api = ApiEngine.createService(ApiFile::class.java)
                .uploadFiles(url = ApiFile.UPLOAD_URL, files = parts)
            onSuccess {
                mDialog.dismiss()
                if (it == null) {
                    failed.back("文件上传失败，服务无数据")
                } else {
                    success.back(it.data)
                }
            }
            onFailed { _, _, e ->
                mDialog.dismiss()
                Timber.tag("文件上传").e(e)
                failed.back("文件上传失败 ${e.toString()}")
            }
        }
    }

    private fun getLocale(): Locale? {
        val config: Configuration = activity.resources.configuration
        var sysLocale: Locale? = null
        sysLocale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            getSystemLocale(config)
        } else {
            getSystemLocaleLegacy(config)
        }
        return sysLocale
    }

    private fun getSystemLocaleLegacy(config: Configuration): Locale? {
        return config.locale
    }

    @TargetApi(Build.VERSION_CODES.N)
    fun getSystemLocale(config: Configuration): Locale? {
        return config.locales[0]
    }

    private fun getFileSize(path: String): Float? {//获取文件大小
        val f = File(path)
        return if (!f.exists()) {
            0f
        } else {
            var size = f.length()
            size.div(1024f).div(1024f)
        }
    }
}